package com.quanyan.place.component;

import java.io.BufferedReader;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.user.AppUserCacheInfo;
import com.quanyan.common.utils.HttpServletRequestWrapper;
import com.quanyan.common.utils.MD5Utils;
import com.quanyan.redisCluster.config.RedisTemplate;
import com.quanyan.redisCluster.utils.RedisKey;


/**
 * @Author Hugo.Wwg
 * @Since 2016-06-02
 */
@Component
public class CommonFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(CommonFilter.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    private void ajaxError(ApiResponseEnum apiResponseEnum, ServletResponse response)
            throws IOException {
        response.getWriter().write(JSON.toJSON(APIResponse.returnFail(apiResponseEnum)).toString());
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Content-Type","application/json");
        String uri = request.getRequestURI();
        String sign = request.getHeader(Constants.USER_SIGN);

        ServletRequest requestWrapper = new HttpServletRequestWrapper(request);
        String reqData = getBodyString(requestWrapper.getReader(), uri);
        
        if (uri.startsWith("/druid/")) {
       	   chain.doFilter(requestWrapper, response);
       	   return;
		}
        
        logger.info("==============请求路径:{}" ,uri);
        logger.info("==============请求数据:{}" ,reqData);
        
        
        //对url进行签名验证
        if(uri.startsWith("/api/place/c/")
                || uri.startsWith("/admin/api/place/")
                || uri.startsWith("/api/place/callback/")
                || uri.startsWith("/admin/api/unitCombine/")
                || uri.startsWith("/admin/api/promotion/")
                || uri.startsWith("/api/place/")) {
            // nop
        }
        else {
            if (reqData == null) {
                ajaxError(ApiResponseEnum.BODY_IS_NULL, response);
                return;
            }
            if(sign == null){
                ajaxError(ApiResponseEnum.SIGN_IS_NULL, response);
                return;
            }
            String md5Sign = MD5Utils.MD5Encode(reqData + Constants.SECRET_KEY);
            if (!sign.equals(md5Sign)) {
                logger.info("-----------签名不一致，客户端签名:{}，服务器签名:{}" ,sign,md5Sign);
                ajaxError(ApiResponseEnum.ILLEGAL_PROTOCOL, response);
                return;
            }

        }

        try{
            String uMsg = request.getHeader(Constants.USER_INFORMATION_MARK);
            Integer userId = -1 ;
            RedisKey redisKey = new RedisKey(uMsg, "");
            AppUserCacheInfo appUserCacheInfo = (AppUserCacheInfo)
                    redisTemplate.getObjectFromC(redisKey, AppUserCacheInfo.class);
            if (appUserCacheInfo != null) {
                 userId = appUserCacheInfo.getUser_id();
                if (userId != null) {
                    request.setAttribute("uid", userId); //uid不为null表示已经登录, 为null表示为游客身份
                }
                else {
                    request.setAttribute("uid", userId);
                }
            }
            else {
                request.setAttribute("uid", userId);
            }

            /**门票扫一扫小程序 及 App端扫一扫 支付**/
            String fitPayType = request.getHeader("fitPayType");
            JSONObject json = JSONObject.parseObject(reqData);
            if (json != null) {
            	 String appTicket = (String)json.get("fitPayType");
            	 if (null != fitPayType || null != appTicket ){
                     if(uri.startsWith("/api/place/ticket/pay") && (
                             (!StringUtils.isEmpty(fitPayType) && fitPayType.equals(Constants.SystemPayType.PLACE_WECHAT_TYPE_FITPAY)) ||
                                     (!StringUtils.isEmpty(appTicket) && appTicket.equals(Constants.SystemPayType.PLACE_APP_TYPE_FITPAY)))){
                         request.setAttribute("uid", -1);
                         userId = -1;
                     }
                 }
			}
            logger.info("================= userCookiesName:{} ==> uid:{} =================", uMsg,userId);
        }catch (Exception e){
            e.printStackTrace();
            request.setAttribute("uid", -1);
        }

        chain.doFilter(requestWrapper, response);
        //logger.warn("Request End，Request URI: " + request.getRequestURI()+ "，Time spent: " + (System.currentTimeMillis() - startTime) + "ms");
    }


    public static String getBodyString(BufferedReader br, String reqUrl) {
        String inputLine;
        String str = "";
        try {
            while ((inputLine = br.readLine()) != null) {
                str += inputLine;
            }
            br.close();
        } catch (IOException e) {
            logger.warn("requestUrl: " + reqUrl + ", Request error: "
                    + e.getMessage() + "Request URI: ");

        }
        return str;
    }

    public static void main(String[] args) {
        String md5Sign = MD5Utils.MD5Encode("{\"placeId\":12907}" + Constants.SECRET_KEY);
        System.out.println(md5Sign);
    }
}
